#include "agp_data.h"
#include "agp_util.h"

#include <vector>
using namespace std;

int agp_vertex::LAST_VID=-1; //keep tracking of IDS

agp_vertex::~agp_vertex()
{

}

void agp_vertex::computeNormal()
{
    normal=::computeNormal(next->pos-pos);
}

///////////////////////////////////////////////////////////////////////////////

// clean up the space allocated
void agp_poly::destroy()
{
    if( head==NULL ) return;
    agp_vertex* ptr=head;
    do{
        agp_vertex * n=ptr->getNext();
        delete ptr;
        ptr=n;
    }while( ptr!=head );
    head=tail=NULL;
}

// Create a empty polygon
void agp_poly::beginPoly()
{
    head=tail=NULL;
}

// Add a vertex to the polygonal chian
void agp_poly::addVertex( double x, double y )
{
    agp_vertex * v=new agp_vertex(Point2d(x,y));
    if( tail!=NULL ){
        tail->setNext(v);
    }
    tail=v;
    if( head==NULL ) head=tail;
}

// finish building the polygon
void agp_poly::endPoly()
{
    if( tail!=NULL ) tail->setNext(head);
    doInit();
}

// initialize property of the this polychain
// Compute normals and find reflective vertices
void agp_poly::doInit()
{
    //compute normals
    agp_vertex* ptr=head;
    size=0;
    do{
        size++;
        ptr->computeNormal();
        ptr=ptr->getNext();
    }while( ptr!=head );
}

istream& operator>>( istream& is, agp_poly& poly)
{
    int vsize; string str_type;
    is>>vsize>>str_type;
    
    if( str_type.find("out")!=string::npos )
        poly.type=agp_poly::POUT;
    else poly.type=agp_poly::PIN;
    
    poly.beginPoly();
    //read in all the vertices
    int iv;
    vector< pair<double,double> > pts; pts.reserve(vsize);
    for( iv=0;iv<vsize;iv++ ){
        double x,y;
        is>>x>>y;
        pts.push_back(pair<double,double>(x,y));
        //double d=x*x+y*y;
    }
    int id;
    for( iv=0;iv<vsize;iv++ ){
        is>>id; id=id-1;
        poly.addVertex(pts[id].first,pts[id].second);
    }
    
    poly.endPoly();
    return is;
}

ostream& operator<<( ostream& os, const agp_poly& p)
{
    os<<p.size<<" "<<((p.type==agp_poly::PIN)?"in":"out")<<"\n";
    agp_vertex * ptr=p.head;
    do{
        os<<ptr->getPos()[0]<<" "<<ptr->getPos()[1]<<"\n";
        ptr=ptr->getNext();
    }while(ptr!=p.head);
    
    for(int i=0;i<p.size;i++) os<<i+1<<" ";
    os<<"\n";
    return os;
}


